package cn.com.chengmandian.bike.service.impl;

import cn.com.chengmandian.bike.model.EbMemberPay;
import cn.com.chengmandian.bike.model.EbRefundInfo;
import cn.com.chengmandian.bike.mapper.EbRefundInfoMapper;
import cn.com.chengmandian.bike.service.*;
import cn.com.chengmandian.core.common.utils.BillNoUtil;
import cn.com.chengmandian.core.web.pojo.LoginUser;
import cn.com.chengmandian.service.bike.constants.*;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.Date;

/**
 * <p>
 * 电单车运营-退款申请 服务实现类
 * </p>
 *
 * @author AutoGenerator
 * @since 2022-10-08
 */
@Service
public class EbRefundInfoServiceImpl extends ServiceImpl<EbRefundInfoMapper, EbRefundInfo> implements IEbRefundInfoService {
    @Autowired
    private IEbRideOrderService rideOrderService;

    @Autowired
    private IEbDepositRecordService depositRecordService;

    @Autowired
    private IEbRidePenaltyService ridePenaltyService;

    @Autowired
    private IEbMemberPayService memberPayService;

    @Autowired
    private IEbMessageInfoService messageInfoService;

    @Autowired
    private IEbMemberMoneyService memberMoneyService;

    @Override
    public EbRefundInfo createRefund(Integer areaId,Integer memberId, Integer businessId, Integer payId, BigDecimal feeRatio,BigDecimal money, RefundBusinessTypeEnum businessTypeEnum, RefundChannelEnum channelEnum, String reason, LoginUser loginUser, String data) {
        EbRefundInfo ebRefundInfo = new EbRefundInfo();
        ebRefundInfo.setRefundNo(BillNoUtil.getSimpleNo("RN-"));
        ebRefundInfo.setMemberId(memberId);
        ebRefundInfo.setAreaId(areaId);
        ebRefundInfo.setBusinessType(businessTypeEnum.getCode());
        ebRefundInfo.setBusinessId(businessId);
        ebRefundInfo.setMoney(money);
        ebRefundInfo.setRefundChannel(channelEnum.getCode());
        ebRefundInfo.setReason(reason);
        ebRefundInfo.setAcceptTime(new Date());
        ebRefundInfo.setStatus(RefundStatusEnum.WAIT_HANDLE.getCode());
        ebRefundInfo.setRefundMoney(money);
        if(ObjectUtil.isNotNull(loginUser) && loginUser.getId() > 0){
            ebRefundInfo.setCreateUser(loginUser.getId());
            ebRefundInfo.setCreateName(loginUser.getName());
        }
        BigDecimal feeMoney = BigDecimal.ZERO;
        if(feeRatio != null && money != null){
            feeMoney = money.multiply(feeRatio).setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        ebRefundInfo.setFeeMoney(feeMoney);
        ebRefundInfo.setFeeRatio(feeRatio);
        ebRefundInfo.setPayId(payId);
        ebRefundInfo.setData(data);
        this.save(ebRefundInfo);
        return ebRefundInfo;
    }

    @Override
    public EbRefundInfo createRefund(Integer areaId, Integer memberId, Integer businessId, Integer payId, BigDecimal feeRatio,BigDecimal money, RefundBusinessTypeEnum businessTypeEnum, RefundChannelEnum channelEnum, String reason, LoginUser loginUser) {
        return this.createRefund(areaId,memberId,businessId, payId, feeRatio,money,businessTypeEnum,channelEnum,reason,loginUser,null);
    }

    /**
     * 退款响应通知
     * @param refundNo
     * @param channelNo
     */
    @Override
    public void refundSuccess(String refundNo, String channelNo) {
        EbRefundInfo refundInfo = this.getOne(new LambdaQueryWrapper<EbRefundInfo>()
                .eq(EbRefundInfo::getRefundNo,refundNo)
                .last("limit 0,1"));
        Assert.notNull(refundInfo,"退款记录不存在:" + refundNo);

        // 退款信息
        this.update(new LambdaUpdateWrapper<EbRefundInfo>()
                .set(EbRefundInfo::getStatus, RefundStatusEnum.REFUND_OK.getCode())
                .set(EbRefundInfo::getCompleteTime, new Date())
                .set(EbRefundInfo::getChannelNo, channelNo)
                .eq(EbRefundInfo::getId, refundInfo.getId()));

        // 支付记录
        EbMemberPay memberPay = memberPayService.getById(refundInfo.getPayId());

        // 已退款金额
        BigDecimal refundMoney = (ObjectUtil.isNull(memberPay.getRefundMoney()) ? BigDecimal.ZERO : memberPay.getRefundMoney()).add(refundInfo.getMoney());
        MemberPayStatusEnum memberPayStatusEnum = MemberPayStatusEnum.PAID;
        if(refundMoney.compareTo(memberPay.getMoney()) >= 0){
            memberPayStatusEnum = MemberPayStatusEnum.REFUND;
        }
        memberPayService.update(new LambdaUpdateWrapper<EbMemberPay>()
                .set(EbMemberPay::getStatus, memberPayStatusEnum.getCode())
                .set(EbMemberPay::getRefundMoney, refundMoney)
                .set(EbMemberPay::getRefundTime, new Date())
                .eq(EbMemberPay::getId, memberPay.getId()));

        // 骑行订单
        if(refundInfo.getBusinessType().equals(RefundBusinessTypeEnum.ORDER.getCode())) {
            rideOrderService.rideRefundSuccess(refundInfo);

            // 非余额支付生成流水
            if(!PayChannelEnum.WALLET.getCode().equals(memberPay.getPayChannel())) {
                memberMoneyService.createPay(memberPay.getAreaId(), memberPay.getMemberId(), MemberMoneyBusinessTypeEnum.RIDE_ORDER_REFUND, memberPay.getBusinessId(), MemberMoneyOperationTypeEnum.SERVICE, refundInfo.getMoney());
            }

            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 "  + DateUtil.now() + " 骑行订单退款成功" + refundInfo.getMoney().doubleValue() + "元，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.ORDER, memberPay.getBusinessId());
            // 押金订单
        }else if(refundInfo.getBusinessType().equals(RefundBusinessTypeEnum.YAJIN.getCode())){
            depositRecordService.refundSuccess(refundInfo);

            // 非余额支付生成流水
            if(!PayChannelEnum.WALLET.getCode().equals(memberPay.getPayChannel())) {
                memberMoneyService.createPay(memberPay.getAreaId(), memberPay.getMemberId(), MemberMoneyBusinessTypeEnum.DEPOSIT_REFUND, memberPay.getBusinessId(), MemberMoneyOperationTypeEnum.SERVICE, refundInfo.getMoney());
            }

            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 "  + DateUtil.now() + " 押金退款成功" + refundInfo.getMoney().doubleValue() + "元，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.DEPOSIT, null);
            // 骑行订单罚款
        } else if (refundInfo.getBusinessType().equals(RefundBusinessTypeEnum.RIDE_PENALTY.getCode())) {
            ridePenaltyService.refundSuccess(refundInfo);

            // 非余额支付生成流水
            if(!PayChannelEnum.WALLET.getCode().equals(memberPay.getPayChannel())) {
                memberMoneyService.createPay(memberPay.getAreaId(), memberPay.getMemberId(), MemberMoneyBusinessTypeEnum.RIDE_ORDER_REFUND, memberPay.getBusinessId(), MemberMoneyOperationTypeEnum.SERVICE, refundInfo.getMoney());
            }

            messageInfoService.addSys(memberPay.getMemberId(), MessageChannelEnum.SYS,
                    "尊敬的用户，您于 "  + DateUtil.now() + " 罚款退款成功" + refundInfo.getMoney().doubleValue() + "元，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.RIDE_PENALTY, memberPay.getBusinessId());
        }
    }
}
